TAKE AWAY POINTS FROM THIS POST
With ggmap you can use Google Maps within the ggplot2 environment.
Delaunay triangulation is a way to compute at the area and centroid of a strangly shaped polygon, and can be computed in R with the deldir pacakge.
Centroids of cities’ important places tend to be by rivers. Unless there is an ocean involved.
To collect my data I went to Wikitravel and looked up four cities: Paris, Berlin, Barecelona, and Prague. I went to the “See” section for each city and wrote down each place reccomended to see that wasn’t a general district and was inside the city limits (e.g. I did not include Versaille for Paris). I think looked up the exact addresses of each landmark on Google Maps and added it to my data.*
With my data in place I began to work with it in R to organize it. I used two packages to start off, dplyr and ggmap. The package dplyr has been discussed previously in this blog [ADD LINK], but ggmap is new. With ggmap you can download maps from various sources, including Google Maps, and plot with it in the ggplot2 environment. The first ggmap call I use is “geocode()”. I can feed it my “address” column from my data frame and it will find the longitude and latitude of my address. With my mutate call I can save these values to two columns.
library(dplyr)
library(ggmap)
# data = read.table("data_locations.txt", header=T, sep="\t") %>%
# mutate(address = as.character(address)) %>%
# rowwise() %>%
# mutate(longitude = geocode(address, source = "google")[1, 1]) %>%
# mutate(latitude = geocode(address, source = "google")[1, 2])
data = read.table("data_temp.txt", header = T, sep="\t")
We can now take a look at the output of the data below.
With our data in place we can start making our maps. This brings us to the second ggmaps call, “get_googlemap()”. With this call I can download city specific maps for my four cities. I can set the type of map (terrain, satellite, roadmap, hybrid), how close to zoom in (integers that range from continent to building), and the size of my map in pixels.
# Get city specific maps
paris_map = get_googlemap(center = "Paris", maptype = "roadmap", zoom = 12, size = c(640, 420))
berlin_map = get_googlemap(center = "Berlin", maptype = "roadmap", zoom = 11, size = c(640, 420))
barcelona_map = get_googlemap(center = "Barcelona", maptype = "roadmap", zoom = 12, size = c(640, 420))
prague_map = get_googlemap(center = "Prague", maptype = "roadmap", zoom = 12, size = c(640, 420))
With our map object saved from Google can now plot our maps and our landmark data points on top. Since I’ll be making roughly the same plot each time I write a function which you can see below. The main difference from a typical ggplot2 plot is instead of using “ggplot()” to start off the plot you use “ggmap()” and then feed it the map we had saved. From then on it takes the same ggplot2 calls as any other plot. For example, we can use “geom_point()” to plot our landmarks. See the maps with landmarks for the four cities below.
# Plot city specific maps with landmarks noted
city_plot = function(city_name, city_map){
ggmap(city_map, extent = "device") +
geom_point(data = subset(data, city == city_name), aes(x = longitude, y = latitude),
color = "#1a9641", size = 4)
}
With our maps and data points in place let’s compute the triangulations for each city. We do this with the deldir package.
library(deldir)
# data_deldir = data %>%
# group_by(city) %>%
# do(deldir(.$longitude, .$latitude)) %>%
# ungroup()
#
#
# data_deldir = data %>%
# nest(-city) %>%
# mutate(col = map2(longitude, latitude, deldir)) %>%
# select(city, col) %>%
# unnest()
### TO BE CHANGED
paris_data = filter(data, city == "Paris")
paris_deldir = deldir(paris_data$longitude, paris_data$latitude)
berlin_data = filter(data, city == "Berlin")
berlin_deldir = deldir(berlin_data$longitude, berlin_data$latitude)
barcelona_data = filter(data, city == "Barcelona")
barcelona_deldir = deldir(barcelona_data$longitude, barcelona_data$latitude)
prague_data = filter(data, city == "Prague")
prague_deldir = deldir(prague_data$longitude, prague_data$latitude)
Now we can update our figures with the triangulations. I’ve again made a function to run one the four maps. First we take our preivously made map with the data points and then we can use “geom_segment()” to draw the edges of the triangles on top. See the four updated maps below.
del_plot = function(city_name, city_map, city_data){
ggmap(city_map, extent = "device") +
geom_segment(data = city_data$delsgs, aes(x = x1, y = y1, xend = x2, yend = y2),
size = 1, color= "black") +
geom_point(data = subset(data, city == city_name), aes(x = longitude, y = latitude),
color = "#1a9641", size = 4)
}
Let’s compare the areas. The area for Paris is 0.004232, Berlin 0.011105, Barelona 0.002051, and Prague 0.002625.
Finally, let’s also calcualte the caculate centroid of the triangulations. To compute the centroids we’ll go back to the output of the “deldir()” call, focusing on the “summary” information. In “summary” we have the x and y
## TO BE CHANGED
paris_deldir_sum = data.frame(paris_deldir$summary) %>%
mutate(city = "Paris")
berlin_deldir_sum = data.frame(berlin_deldir$summary) %>%
mutate(city = "Berlin")
barcelona_deldir_sum = data.frame(barcelona_deldir$summary) %>%
mutate(city = "Barcelona")
prague_deldir_sum = data.frame(prague_deldir$summary) %>%
mutate(city = "Prague")
data_deldir_sum = paris_deldir_sum %>%
bind_rows(berlin_deldir_sum) %>%
bind_rows(barcelona_deldir_sum) %>%
bind_rows(prague_deldir_sum)
data_deldir_centroid = data_deldir_sum %>%
group_by(city) %>%
summarise(cent_x = sum(x * del.wts),
cent_y = sum(y * del.wts)) %>%
ungroup()
Plot figures with centroid noted.
# Make plots with centroid
cent_plot = function(city_name, city_map){
city_map +
geom_point(data = subset(data_deldir_centroid, city == city_name),
aes(x = cent_x, y = cent_y),
size = 8, color= "#d7191c")
}
Based on these maps it looks like